package encontrar;

import Util.Acentos;
import entidades.Sentido;
import entidades.Status;
import entidades.Vias;
import entidades.ViasPosicao;
import hibernate.HibernateUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hibernate.Session;

/**
 *
 * @author Gláucio
 */
public class ListaTokens {

  private List<Token> lista = new ArrayList();
  private List<ViasPosicao> viasPosicao = new ArrayList();
  private List<Vias> vias = new ArrayList();
  private List<Status> status = new ArrayList();
  private List<Sentido> sentido = new ArrayList();

  public ListaTokens() {
  }

  public void setStatus(List<Status> status) {
    this.status = status;
  }

  public void setVias(List<Vias> vias) {
    this.vias = vias;
  }

  public void setViasPosicao(List<ViasPosicao> viasPosicao) {
    this.viasPosicao = viasPosicao;
  }

  public void setSentido(List<Sentido> sentido) {
    this.sentido = sentido;
  }

  private String tiraPlural(String post, String plural, String singular) {
    String[] tokens = post.split(" ");

    boolean achou = false;

    for (int x = 0; x < tokens.length; x++) {
      String token = tokens[x];
      if (token.equals(plural)) {
        tokens[x] = singular;
        achou = true;
      } else if ((achou) && token.equals("E")) {
        tokens[x] = "E " + singular;
        achou = false;
      } else if ((achou) && token.equals("ATE")) {
        tokens[x] = "ATE " + singular;
        achou = false;
      }
    }

    post = "";
    for (int x = 0; x < tokens.length; x++) {
      post += tokens[x] + " ";
    }

    return post;
  }

  private String normalizar(String post) {
    post = post.toUpperCase();
    post = Acentos.retirarAcentos(post);
    post = post.replace("    ", " ");
    post = post.replace("   ", " ");
    post = post.replace("  ", " ");

    post = tiraPlural(post, "MARGINAIS", "MARGINAL");
    post = tiraPlural(post, "RUAS", "RUA");
    post = tiraPlural(post, "AVENIDAS", "AVENIDA");
    post = tiraPlural(post, "PRACAS", "PRACA");
    post = tiraPlural(post, "ALAMEDAS", "ALAMEDA");
    post = tiraPlural(post, "TUNEIS", "TUNEL");
    post = tiraPlural(post, "VIAS", "VIA");
    post = tiraPlural(post, "RODOVIAS", "RODOVIA");
    post = tiraPlural(post, "ESTRADAS", "ESTRADA");
    post = tiraPlural(post, "PONTES", "PONTE");
    post = tiraPlural(post, "RADIAIS", "RADIAL");
    post = tiraPlural(post, "VIADUTOS", "VIADUTO");

    return post;
  }

  public List<Token> separaTokens(String post) {
    //1. Encontrar as palavras reservadas da classes ViasPosicao
    for (int i = 0; i < viasPosicao.size(); i++) {
      String palavra = viasPosicao.get(i).getNomeViaPosicao().replace("\r", "");
      int idx = post.indexOf(palavra);
      if (idx > 0) {
        lista.add(new Token(palavra, Token.Tipo.ViaPosicao, idx, palavra.length()));
        //coloca * na palavra reservada
        String lixo = "";
        for (int j = 0; j < palavra.length(); j++) {
          lixo += "*";
        }
        post = post.replace(palavra, lixo);
      }
    }

    //2. Encontrar as palavras reservadas da classe Sentido
    for (int i = 0; i < sentido.size(); i++) {
      String palavra = sentido.get(i).getNomeSentido().replace("\r", "");
      int idx = post.indexOf(palavra);
      if (idx > 0) {
        lista.add(new Token(palavra, Token.Tipo.Sentido, idx, palavra.length()));
        //coloca * na palavra reservada
        String lixo = "";
        for (int j = 0; j < palavra.length(); j++) {
          lixo += "*";
        }
        post = post.replace(palavra, lixo);
      }
    }

    //3. Encontrar as palavras reservadas da classe Vias
    for (int i = 0; i < vias.size(); i++) {
      String palavra = vias.get(i).getNomeVia().replace("\r", "");
      int idx = post.indexOf(palavra);
      if (idx > 0) {
        lista.add(new Token(palavra, Token.Tipo.Via, idx, palavra.length()));
        //coloca * na palavra reservada
        String lixo = "";
        for (int j = 0; j < palavra.length(); j++) {
          lixo += "*";
        }
        post = post.replace(palavra, lixo);
      }
    }

    //4. Encontrar as palavras reservadas da classe Status
    for (int i = 0; i < status.size(); i++) {
      String palavra = status.get(i).getNomeStatus().replace("\r", "");
      int idx = post.indexOf(palavra);
      if (idx > 0) {
        lista.add(new Token(palavra, Token.Tipo.Status, idx, palavra.length()));
        //coloca * na palavra reservada
        String lixo = "";
        for (int j = 0; j < palavra.length(); j++) {
          lixo += "*";
        }
        post = post.replace(palavra, lixo);
      }
    }

    //5. Encontrar as palavras "magicas"
    post = " " + post + " ";
    String[] tokens = post.split(" ");
    int offset = 0;
    for (int i = 0; i < tokens.length; i++) {
      String t = tokens[i];
      offset = post.indexOf(" " + t + " ", offset);

      if (t.equals("E")) {
        lista.add(new Token("E", Token.Tipo.E, offset, 1));
      } else if (t.equals("ENTRE")) {
        lista.add(new Token("ENTRE", Token.Tipo.ENTRE, offset, 5));
      } else if (t.equals("ATE")) {
        lista.add(new Token("ATE", Token.Tipo.ATE, offset, 3));
      } else if (t.equals("DA") || t.equals("DAS")) {
        lista.add(new Token("DA", Token.Tipo.DA, offset, 2));
      } else if (t.equals("DE")) {
        lista.add(new Token("DE", Token.Tipo.DE, offset, 2));
      } else if (t.equals("DO") || t.equals("DOS")) {
        lista.add(new Token("DO", Token.Tipo.DO, offset, 2));
      } else if (t.equals("DESDE")) {
        lista.add(new Token("DESDE", Token.Tipo.DESDE, offset, 2));
      }
    }

    Collections.sort(lista);

    return lista;
  }

  public static void main(String args[]) {
    ListaTokens l = new ListaTokens();

    Session s = HibernateUtil.getSessionFactory().openSession();
    l.setVias(s.createQuery("from Vias order by bit_length(nomeVia) desc").list());
    l.setViasPosicao(s.createQuery("from ViasPosicao order by bit_length(nomeViaPosicao) desc").list());
    l.setStatus(s.createQuery("from Status order by bit_length(nomeStatus) desc").list());
    l.setSentido(s.createQuery("from Sentido").list());

    //List<Sentido> sentido = s.createQuery("from Sentido").list();
    //List<Posicao> posicao = s.createQuery("from Posicao order by prioridade").list();

    String in = "As Marginais do Tietê e Pinheiros tem 10 km de lentidão, sentido centro, das Pontes Velha Fepasa ate  BANDEIRA.";
    in = l.normalizar(in);
    System.out.println(in);
    List<Token> a = l.separaTokens(in);

    for (int i = 0; i < a.size(); i++) {
      Token t = a.get(i);
      System.out.println(t.getValor() + " - " + t.getTipo() + " - " + t.getPosicao() + " - " + t.getTamanho());
    }

  }
}
